import type { App, VNode } from "vue";
import { createApp, createVNode, reactive } from "vue";
import { default as ProModal, type ProModalProps } from "./../ProModal";

/**模态框操作属性 */
interface ModalOptions extends Partial<ProModalProps> {
  /**图标，渲染到标题左侧 */
  icon?: VNode | (() => VNode);
  /**内容信息，渲染到默认插槽 */
  content?: string | VNode | (() => VNode);
}

/**Hooks 方式打开模态框 */
export function useModal() {
  const baseClassName = ".ant-pro-modal-hooks";
  /**挂载实例 */
  let appInstance: App<Element> | null = null;
  let container: HTMLDivElement | null = document.querySelector(baseClassName);

  /**模态框状态 */
  const state = reactive<ModalOptions>({
    open: false,
    width: 416,
    minWidth: 416,
    minHeight: 156,
  });

  // 初始挂载DOM
  const initializeApp = () => {
    if (appInstance) return;
    const app = createApp({
      render() {
        const { getContainer, content, ...restState } = state;
        return createVNode(
          ProModal,
          { ...restState, getContainer: baseClassName },
          { default: () => content }
        );
      },
    });

    if (!container) {
      container = document.createElement("div");
      container.className = "ant-pro-modal-hooks";
      document.body.appendChild(container);
    }
    app.mount(container);
    appInstance = app;
  };

  /**打开 */
  const open = (options: ModalOptions) => {
    Object.assign(state, options);

    // 每次打开时都初始检查
    initializeApp();

    // 有图标和标题时，占用标题插槽
    if (state.icon && state.title) {
      state.title = [state.icon, state.title];
    }

    state.onOk = (e: MouseEvent) => {
      options.onOk?.(e);
      close();
    };
    state.onCancel = (e: MouseEvent) => {
      options.onCancel?.(e);
      close();
    };
    state.open = true;
  };

  /**关闭 */
  const close = () => {
    state.open = false;

    // 关闭销毁时，移除挂载DOM
    if (state.destroyOnClose) {
      // 延时以等待关闭动画完成
      setTimeout(() => {
        if (appInstance && container) {
          appInstance.unmount();
          document.body.removeChild(container);
          appInstance = null;
          container = null;
        }
      }, 300);
    }
  };

  return {
    open,
    close,
  };
}
